package com.xuecheng.learning.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.api.content.model.dto.TeachplanDTO;
import com.xuecheng.api.learning.model.dto.CourseRecordDTO;
import com.xuecheng.api.order.model.pay.PayCodeUrlResult;
import com.xuecheng.api.search.model.dto.CoursePubIndexDTO;
import com.xuecheng.common.domain.code.CommonErrorCode;
import com.xuecheng.common.domain.response.RestResponse;
import com.xuecheng.common.exception.ExceptionCast;
import com.xuecheng.common.util.JsonUtil;
import com.xuecheng.common.util.StringUtil;
import com.xuecheng.learning.agent.CoursePubIndexApiAgent;
import com.xuecheng.learning.agent.MediaApiAgent;
import com.xuecheng.learning.common.constant.LearningErrorCode;
import com.xuecheng.learning.convert.CourseRecordConvert;
import com.xuecheng.learning.entity.CourseRecord;
import com.xuecheng.learning.mapper.CourseRecordMapper;
import com.xuecheng.learning.service.CourseRecordService;
import io.seata.common.util.CollectionUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 选课记录 服务实现类
 * </p>
 */
@Slf4j
@Service
public class CourseRecordServiceImpl extends ServiceImpl<CourseRecordMapper, CourseRecord> implements CourseRecordService {

    @Autowired
    private CoursePubIndexApiAgent indexApiAgent;

    @Autowired
    private MediaApiAgent mediaApiAgent;

    /**
     * 根据课程发布ID和用户名称查询用户的学习记录
     *
     * @param coursePubId 课程发布ID
     * @param username    用户名称
     * @return 选课记录
     */
    @Override
    public CourseRecordDTO getRecordByCoursePubId(Long coursePubId, String username) {
        if (ObjectUtils.isEmpty(coursePubId) || StringUtil.isBlank(username)) {
            ExceptionCast.cast(CommonErrorCode.E_100101);
        }

        // 根据条件查询用户的学习记录(一个人对一门课只有一个学习记录)
        LambdaQueryWrapper<CourseRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CourseRecord::getCoursePubId, coursePubId);
        queryWrapper.eq(CourseRecord::getUserName, username);
        CourseRecord courseRecord = this.getOne(queryWrapper);

        // 返回学习记录数据
        CourseRecordDTO courseRecordDTO = null;
        if (ObjectUtils.isEmpty(courseRecord)) {
            courseRecordDTO = new CourseRecordDTO();
        } else {
            courseRecordDTO = CourseRecordConvert.INSTANCE.entity2dto(courseRecord);
        }
        return courseRecordDTO;
    }

    /**
     * 订单支付后创建用户学习记录
     *
     * @param username    用户名称
     * @param coursePubId 课程发布ID
     * @return
     */
    @Override
    @Transactional
    public RestResponse<CourseRecordDTO> createCourseRecord4s(String username, Long coursePubId) {
        // 校验关键数据
        if (ObjectUtils.isEmpty(coursePubId) || StringUtil.isBlank(username)) {
            ExceptionCast.cast(CommonErrorCode.E_100101);
        }

        // 从索引库中查询课程发布信息
        RestResponse<CoursePubIndexDTO> response = indexApiAgent.getCoursePubIndexById4s(coursePubId);
        if (!response.isSuccessful()) {
            ExceptionCast.castWithCodeAndDesc(response.getCode(), response.getMsg());
        }
        // 获取课程发布数据
        CoursePubIndexDTO coursePub = response.getResult();

        // 从课程发布中获取课程计划数据
        String teachplanJson = coursePub.getTeachplan();
        TeachplanDTO teachplanDTO = JsonUtil.jsonToObject(teachplanJson, TeachplanDTO.class);
        // 获取第一章
        List<TeachplanDTO> secondTeachplanNodes = teachplanDTO.getTeachPlanTreeNodes();
        if (CollectionUtils.isEmpty(secondTeachplanNodes)) {
            ExceptionCast.cast(LearningErrorCode.E_202205);
        }
        TeachplanDTO secondTeachplan = secondTeachplanNodes.get(0);
        if (ObjectUtils.isEmpty(secondTeachplan)) {
            ExceptionCast.cast(LearningErrorCode.E_202205);
        }

        // 获取第一小节
        List<TeachplanDTO> thirdTeachplanNodes = secondTeachplan.getTeachPlanTreeNodes();
        if (CollectionUtils.isEmpty(thirdTeachplanNodes)) {
            ExceptionCast.cast(LearningErrorCode.E_202205);
        }
        TeachplanDTO thirdTeachplan = thirdTeachplanNodes.get(0);
        if (ObjectUtils.isEmpty(thirdTeachplan)) {
            ExceptionCast.cast(LearningErrorCode.E_202205);
        }

        // 保存用户学习记录
        LambdaQueryWrapper<CourseRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CourseRecord::getUserName, username);
        queryWrapper.eq(CourseRecord::getCoursePubId, coursePubId);
        CourseRecord courseRecord = this.getOne(queryWrapper);

        boolean result = false;
        if (ObjectUtils.isEmpty(courseRecord)) {
            // 新增操作
            courseRecord = new CourseRecord();
            courseRecord.setUserName(username);
            courseRecord.setCompanyId(coursePub.getCompanyId());
            courseRecord.setCourseId(coursePub.getCourseId());
            courseRecord.setCoursePubId(coursePub.getIndexId());
            courseRecord.setCoursePubName(coursePub.getName());
            courseRecord.setTeachmode(coursePub.getTeachmode());
            courseRecord.setTeachplanId(thirdTeachplan.getTeachPlanId());
            courseRecord.setTeachplanName(thirdTeachplan.getPname());
            // 支付状态为已支付状态
            courseRecord.setPaid(Integer.valueOf(PayCodeUrlResult.PAIED));
            result = this.save(courseRecord);
        } else {
            // 更新操作
            LambdaUpdateWrapper<CourseRecord> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.set(CourseRecord::getTeachplanId, thirdTeachplan.getTeachPlanId());
            updateWrapper.set(CourseRecord::getTeachplanName, thirdTeachplan.getPname());
            // 支付状态为已支付状态
            updateWrapper.set(CourseRecord::getPaid, Integer.valueOf(PayCodeUrlResult.PAIED));
            updateWrapper.set(CourseRecord::getChangeDate, LocalDateTime.now());
            updateWrapper.eq(CourseRecord::getId, courseRecord.getId());
            result = this.update(updateWrapper);
        }

        ExceptionCast.cast(!result, LearningErrorCode.E_202204);

        // 返回最新数据
        CourseRecord po = this.getById(courseRecord.getId());
        CourseRecordDTO courseRecordDTO = CourseRecordConvert.INSTANCE.entity2dto(po);
        return RestResponse.success(courseRecordDTO);
    }


}
